package org.breathe.command.impl.list;

import org.breathe.command.Command;
import org.breathe.command.CommandType;
import org.breathe.datastruct.RedisBytes;
import org.breathe.datastruct.RedisData;
import org.breathe.datastruct.impl.RedisList;
import org.breathe.protocal.Resp;
import org.breathe.protocal.decode.BulkString;
import org.breathe.protocal.decode.Errors;
import org.breathe.server.core.RedisCore;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author: breathe
 * @createTime: 2025-05-13
 */
public class LPush implements Command {
    private RedisBytes key;
    private List<RedisBytes> elements;
    private RedisCore redisCore;
    public LPush(RedisCore redisCore) {
        this.redisCore = redisCore;
    }
    @Override
    public CommandType getType() {
        return CommandType.LPUSH;
    }

    @Override
    public void setContext(Resp[] array) {
        if (array.length < 3) {
            throw new IllegalArgumentException("param not enough");
        }
        key = ((BulkString)array[1]).getContent();
        elements = Arrays.stream(array)
                .skip(2)
                .map(BulkString.class::cast)
                .map(BulkString::getContent)
                .collect(Collectors.toList());
    }

    @Override
    public Resp handle() {
        RedisData redisData = redisCore.get(key);
        RedisList redisList;
        if (redisData == null) {
            redisList = new RedisList();
        } else if (redisData instanceof RedisList list) {
            redisList = list;
        } else {
            return new Errors("key not exist");
        }
        RedisBytes[] elementsArray = elements.toArray(new RedisBytes[0]);
        redisList.lPush(elementsArray);
        redisCore.put(key, redisList);
        int size = redisList.size();
        return new BulkString(new RedisBytes(String.valueOf(size).getBytes()));
    }

    @Override
    public boolean writeCommand() {
        return true;
    }
}
